#ifndef WEBSERVER_H
#define WEBSERVER_H
//#include "WProgram.h"

#include "domino.h"
#include <avr/pgmspace.h>

//! Network web server instance
Server Webserver(80);

prog_char str_httplocation[] PROGMEM   = "Location: ";
//prog_char str_ct_html[] PROGMEM = "Content-Type: text/html\n";
prog_char str_url_css[] PROGMEM        = "http://opendomo.com/od/c.css";
prog_char str_html_title[] PROGMEM     = "<html><head><title>Domino</title>";
prog_char str_html_viewport[] PROGMEM  = "<meta name=viewport content='width=320'/>";
prog_char str_html_css[] PROGMEM       = "<link rel=stylesheet type='text/css' href='";
prog_char str_html_endhead[] PROGMEM   = "</head><body>";
prog_char str_htmlfooter[] PROGMEM     = "</ul><a id=ftr href='http://opendomo.com'> </a>";
prog_char str_fmt_html[] PROGMEM       = "<li><b>%s %s</b><i>%s</i></li>\n";
prog_char str_fmt_endhtml[] PROGMEM    = "\n</body></html>";
prog_char str_fmt_field[] PROGMEM      = "<li id='%s' class='%s'><b>%s</b><a class='%s'";
prog_char str_fmt_lnkoff[] PROGMEM     = " href='set+%s+off' ";
prog_char str_fmt_lnkon[] PROGMEM      = " href='set+%s+on' ";
prog_char str_fmt_lnkao[] PROGMEM      = "<a href='set+%s+%s' class='%s'>%c</a>";
prog_char str_fmt_default[] PROGMEM    = ">%s</a></li>\n";

//PROGMEM prog_char str_url_css[] = "Location: http";
//PROGMEM prog_char str_url_css[] = "://opendomo.org/files/domino.css";

#define CONTENT_TYPE_TEXTHTML 1
#define CONTENT_TYPE_CSS 2

void printContentType(byte content){
  	Webserver.print("Content-Type: ");
	switch(content){
  		case CONTENT_TYPE_CSS:
  			Webserver.println("text/css");
  			break;
  		case CONTENT_TYPE_TEXTHTML:
  			Webserver.println("text/html");	
			break;
  	}
   	Webserver.println();	
}

void initWebServer(){
	Webserver.begin();
}

void printHTTPHeader(short code){
  char buffer[30];
	Webserver.print("HTTP/1.1 ");
	Webserver.println(code);
	switch(code){
		case 301:
			Webserver.print("Location: ");
 Webserver.println(flstrn(str_url_css,buffer,30));
			break;
		case 307:
			Webserver.println("Location: /lst");
			break;

	}
	//Webserver.println();
}

void printHTMLHeader(){
	char buffer[50];
  	printContentType(CONTENT_TYPE_TEXTHTML);
	Webserver.println(flstrn(str_html_title, buffer, 50)); 
	Webserver.println(flstrn(str_html_viewport,buffer,50));
	Webserver.print(flstrn(str_html_css,buffer,50));
	Webserver.print(flstrn(str_url_css,buffer,50));
	Webserver.println("'/>");
	Webserver.println(flstrn(str_html_endhead,buffer,50));	
}
void printHTMLFooter(){
	char buffer[50];
 	Webserver.println(flstrn(str_htmlfooter,buffer,50));
 	Webserver.println(flstrn(str_fmt_endhtml,buffer,50));
	delay(10);
}

char processHTTPQuery(char *query)
{
	byte i;
	Serial.print("D:q=");
	Serial.println(query);
	
	int code = 0;

	output = HTTP;
	if (query[5] != ' ') // if URI != "/" 
	{
		for (i = 5; i < BUFFERSIZE; i++) {	// Skip the first 5 bytes (" GET / ")
			if (query[i] == 'H')
				query[i] = 0;	// ... stopping in " HTTP / 1.1 "
			query[i - 5] = query[i];
		}
	
		code = (query[0] - 96) << 10;
		code += (query[1] - 96) << 5;
		code += (query[2] - 96);
	}
	switch(code){
		case 0:
#ifdef MEGA
			printHTTPHeader(200);
			printHTMLHeader();
			Webserver.println("</head><body onload=\"window.location='lst'\">");
			//! @todo: preload all the images and resources for smooth display
#else
  			printHTTPHeader(307);
#endif
			break;

		case CMD_CSS:
			printHTTPHeader(301);
			break;

		case CMD_SET:
			output = SERIALPORT; // no output on HTTP!
			processInstruction(query);
			printHTTPHeader(307);
			break;
#ifdef MEGA
//		case CMD_LST:
#endif
		case CMD_LST:
			printHTTPHeader(200);
			printHTMLHeader();
			writef(HTTP,"<ul class='%s'>\n",query);
			processInstruction(query);
			printHTMLFooter();
			break;
		default:
			Serial.println(query);
			Serial.println(code);

	}
	//wclient.println(" <li><a href=/>&lt;&lt; Back </a></li></ul>");
	delay(100);
	return true;
}



void http_listPortsLine(char *pname, char *ptype, char *pvalue)
{
 	char buffer[50];
	//int value=0;
	if (ptype[1]=='-') ptype[1]=0; // cut the strings 
	if (ptype[2]=='-') ptype[2]=0;
	if (pvalue[2]==' ') pvalue[2]=0;
	if (pvalue[3]==' ') pvalue[3]=0;



	if (ptype[0]=='X') return; // Disabled ports. Don't print


	// <li class='type'><b>fname</b><a class='value'  
	writef(HTTP,flstrn(str_fmt_field,buffer,50),pname, ptype, pname, pvalue);

	if(ptype[0]=='D' && ptype[1]=='O') // Digital output
	{
//		writef(HTTP,flstrn(str_fmt_field,buffer,50),ptype);
//		writef(HTTP,flstrn(str_fmt_field_name,buffer,50),pname);
		if (pvalue[1]=='N')
		{

			writef(HTTP,flstrn(str_fmt_lnkoff,buffer,50), pname);
		}else {
			writef(HTTP,flstrn(str_fmt_lnkon,buffer,50), pname);
		}
		//Webserver.println("> </a></li>");
	}
	else 
        if(ptype[0]=='A' && ptype[1]=='O') // Analog output
	{
  		char num[]="00000";
  		writef(HTTP,"></a><div class='slider'>");
		for (int p=0;p<=10;p++){
			num[3]=p+48;
			if (p==10){num[2]='1';num[3]='0';}
			if(strncmp(num,pvalue,4)==0)
				writef(HTTP,flstrn(str_fmt_lnkao,buffer,50),pname,num,"sl",'+');
			else
				writef(HTTP,flstrn(str_fmt_lnkao,buffer,50),pname,num,"un",'-');			
		}
		pvalue[0]=' ';
		pvalue[1]=' ';
		writef(HTTP,"</div><a class=slval ");
	}
	else if (ptype[0]=='A' && ptype[1]=='I') // Analog input
	{
		if (pvalue[0]=='0'){
			pvalue[0]=' '; 
			if (pvalue[1]=='0') {
  				pvalue[1]=' ';
  				if (pvalue[2]=='0') pvalue[2]=' ';
  			}
		}
	} 

	writef(HTTP,flstrn(str_fmt_default,buffer,50),pvalue);
	delay(1);
}

void HTTPformattedPrint(char *a, char *b, char *c)
{
  char buffer[30];
	writef(HTTP,flstrn(str_fmt_html,buffer,30), a, b, c);
}

/// This function reads a command from the HTTP port
int readFromHTTPPort(char *instruction)
{
  char pos=0;
  char linecount=0;
  //boolean uristarted = false;
  // listen for incoming clients
  Client client = Webserver.available();
  if (client) {
    //Serial.println("REQ");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        //Serial.print(".");
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
 /*         client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/plain");
          client.println();
          client.println("ok");

          // output the value of each analog input pin
          for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
            client.print("<li>analog input ");
            client.print(analogChannel);
            client.print(" is ");
            client.print(analogRead(analogChannel));
            client.println("</li>");
          }
          client.print(instruction);
          client.print("<li>memory:");
          client.print(freeMemory());
          client.println("</li>");*/
          processHTTPQuery(instruction);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          linecount++;
          currentLineIsBlank = true;
          pos=0;
        } 
        else if (c != '\r') {
          if (linecount==0 && pos<20){
             instruction[pos]=c;
             pos++;
             instruction[pos]=0;
          }
          //if (c=='/' && linecount==0) uristarted = !uristarted;
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    //return (pos>0);
    return true;
  } 
/*	char b;
	byte i=0;
	boolean uri_started = false;
//	char query[BUFFERSIZE+10];

	Client wclient = Webserver.available();

	if (wclient) {		// Only if there is a request, we continue
		Serial.println("REQ");
		query[0] = 0;	// clear the string
		i = 0;		// Point at the beginning of the string
		while (wclient.available() > 0) {
			b = wclient.read();
			Serial.print(b);
			switch (b) {
			case -1:	// Null char
			case 0:	// Null char
			case 10:	// LF: Should not happen!
				break;
			case '/': 
				i=0;
				uri_started = true;
				break;
			case 13:
			case ' ':
				if (uri_started){ 
					output = HTTP;
					//processHTTPQuery(query);
//					delay(10);
					wclient.flush();
					wclient.stop();
					Serial.print("N:httpq=");
					Serial.println(query);
					return true;
 				}
 				i=0;
				break;
			default:
				if ((i < BUFFERSIZE) && (b >= 32 && b <= 126)) {
					query[i] = b;
					i++;
					query[i] = 0;
				}else if (i>30) {
					//wclient.flush();
					//wclient.stop();

				}
				break;
			}
		}
		delay(10);
		wclient.stop();
	}*/
	return false;
}

int selectCSSFile(char *file){

}
#endif
